package com.zzuli.yxy.config;

import com.zzuli.yxy.filter.JwtAuthenticationTokenFilter;
import com.zzuli.yxy.handler.AuthenticationEntryPointImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

/**
 * Spring Security 配置类
 * @auther pony
 * @create 2023-03-05 16:16
 */
@Configuration
@EnableWebSecurity //IOC容器中注入了WebSecurityConfiguration这个类
@EnableGlobalMethodSecurity(prePostEnabled = true) //开启使用Security提供的注解，prePostEnabled 方法之前
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Autowired
    private AccessDeniedHandler accessDeniedHandler; //授权失败处理器

    @Autowired
    private AuthenticationEntryPointImpl authenticationEntryPoint; //认证失败处理器

    @Autowired
    private JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;
    // 需要放行的url
    private static final String[] URL_WHITELIST = {
            "/employee/login/**", //登录
            "/employee/getVerifyCode",
            "/**/outExcel",
    };

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 开启跨域 以及csrf攻击 关闭
        http
                //前后端分离，关闭 csrf
                .csrf().disable()
                //用户登录信息默认是存到 session 中的，前后端分离不用 session 了，所以禁用掉
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                //要放行的接口，允许匿名访问
                .antMatchers(URL_WHITELIST).anonymous()
                //除了上面的所有请求全部需要鉴权认证
                .anyRequest().authenticated();
        //添加过滤器
        http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);

        //配置异常处理器
        http.exceptionHandling()
                //配置认证失败异常处理器
                .authenticationEntryPoint(authenticationEntryPoint)
//                //配置授权失败异常处理器
                .accessDeniedHandler(accessDeniedHandler);

        //跨域配置
        http.cors();
    }
}
